/**
 * @author Kristian Mandrup
 * @date May 25, 2009
 * @version 0.1
 * 
 * m3gen :: Branch functions
 * 
 * Utility functions for parsing and operating on branches
 */ 

/*

languageData: {
	en: {
		title: 'My boys'
	},
	dk: {
		title: 'Mine drenge'
	},
	'default': {
		icon: 'folder.png'
	}


BTR_languageData: {
		en: {
			icon: 'folder_en.png'
		},
		dk: {
			icon: 'folder_dk.png'
		},
		'default': {
			icon: 'folder_en.png'
		}

 */

m3gen.Base.prototype.getBranchTypeRule_from_BranchDefinition = function(branchDefinition){
	var branchType = this.getBranchType(branchDefinition);
	if (this.isValidString(branchType)) {
		// get branchTypeRule
		return this.getBranchTypeRule(branchType);
	} else return null;
}
		
/**
 * Merge language data
 * @param {Object} langData
 * @param {Object} btr_lang_data
 */
m3gen.Base.prototype.mergeLanguageData = function(langData, btr_lang_data) {
	var iterateKeys = function(targetKeySet, sourceKeySet, reverse) {
		var iterator = sourceKeySet;
		if (reverse == true)
			iterator = targetKeySet;
		for each (var key in sourceKeySet) {
			// add this key/value pair to this language object
			if (this.isValidObj(sourceKeySet[key]))
				targetKeySet[key] = sourceKeySet[key];
		}		
	}
	
	
	for each (var key in langData) {
		var btr_lang = btr_lang_data[key];
		var btr_lang_default = btr_lang_data['default'];		
		var lang = langData[key];
		// fill with defaults first
		iterateKeys(lang, btr_lang_default);
		iterateKeys(lang, btr_lang);
		iterateKeys(lang, btr_lang, true);		
	}
	
	return langData;	
}

/**
 * 
 * @param {Object} branchTypeRule
 */
m3gen.Base.prototype.getBranchTypeRuleLanguageData = function(branchTypeRule){
	return branchTypeRule.languageData;
}

/**
 * 
 * @param {Object} branchTypeRule
 */
m3gen.Base.prototype.getBranchTypeRuleState = function(branchTypeRule){
	return branchTypeRule.state;
}

/**
 * 
 * @param {Object} branchTypeRule
 */
m3gen.Base.prototype.getBranchTypeRuleIcon = function(branchTypeRule){
	return branchTypeRule.icon;
}

/**
 * TODO: Test this!
 * 
 * @param {Object} childrenForNodeObj
 * @param {Object} jsTreeBranch_children
 */
m3gen.Base.prototype.addBranchToJsTreeChildArray = function (childrenForNodeObj, jsTreeBranch_children) {
	this.concatJsTreeNodeArrays(childrenForNodeObj, jsTreeBranch_children);
}

/**
 * 
 * @param {Object} branchDefinition
 */
m3gen.Base.prototype.getBranchId = function(branchDefinition){
	return branchDefinition.id;
}

/**
 * 
 * @param {Object} branchDefinition
 */
m3gen.Base.prototype.getBranchLanguageData = function(branchDefinition){
	return branchDefinition.languageData;
} 

/**
 * 
 * @param {Object} branchDefinition
 */
m3gen.Base.prototype.getBranchTitle = function(branchDefinition){
	return branchDefinition.title;
}

/**
 * 
 * @param {Object} branchDefinition
 */
m3gen.Base.prototype.getBranchType = function(branchDefinition){
	return branchDefinition.branchType;
}

// resolved content
/**
 * 
 * @param {Object} resolvedContent
 */
m3gen.Base.prototype.decideNodeObjId = function(resolvedContent) {
	var id = this.getObjDef(resolvedContent.id, 'no_id');
	if (this.getUseUniqueId()) {
		id = this.getObjDef(resolvedContent.unique_id, id);
	}
	return id;
}

/**
 * 
 * @param {Object} resolvedContent
 */
m3gen.Base.prototype.getResolvedAttributes = function(resolvedContent) {
	return this.validObj(resolvedContent.attributes);
}

/**
 * 
 * @param {Object} resolvedContent
 */
m3gen.Base.prototype.getResolvedState = function(resolvedContent) {
	var state = this.validObj(resolvedContent.state);
	if (this.isValidObj(state) && !this.isValidBranchState(state)) 
		state = m3gen.constants.branch.defaultFolderState;
	return state;
}

/**
 * 
 * @param {Object} resolvedContent
 */
m3gen.Base.prototype.getResolvedIcon = function(resolvedContent) {
	var icon = this.validObj(resolvedContent.icon);
	// if icon != null then try to set it to sth. valid
	if (this.isValidObj(icon) && !this.isValidString(icon))
		icon = m3gen.constants.node.defaultIcon		
	return icon;
}

/**
 * 
 * @param {Object} resolvedContent
 */
m3gen.Base.prototype.getResolvedTitle = function(resolvedContent) {
	var title = this.validObj(resolvedContent.title);	
	// if icon != null then try to set it to sth. valid
	if (this.isValidObj(title) && !this.isValidString(title))
		title = m3gen.constants.node.defaultTitle		
	return title;
}

/**
 * 
 * @param {Object} resolvedContent
 */
m3gen.Base.prototype.getResolvedLanguageData = function(resolvedContent) {
	return this.validObj(resolvedContent.languageData);	
}

/**
 * 
 * @param {Object} resolvedContent
 */
m3gen.Base.prototype.getResolvedData = function(resolvedContent) {
	return this.validObj(resolvedContent.data);		
}


/**
 * 
 * @param {Object} resolvedContent
 */
m3gen.Base.prototype.isResolvedBranch = function(resolvedContent) {
	return resolvedContent.branch || false;
}


// branchObj

/**
 * Get branchNode children
 * @param {Object} branchObj
 */
m3gen.Base.prototype.getBranchNodeChildren = function(branchObj){
	return branchObj.children;
}

// Branch Type

/**
 * Get branch types of active ruleSet
 */
m3gen.Base.prototype.getActiveBranchTypes = function(){		
	return this.getActiveRuleSet().branchTypes || this.getRuleSetConfiguration().branchTypes;
}


// Branch Rule

/**
 * Get branch rules of active ruleSet
 */
m3gen.Base.prototype.getBranchRules = function() {
	return this.getActiveRuleSet().branchRules;
};

/**
 * Get the branch rules for parsing child instance nodes
 */
m3gen.Base.prototype.getInstanceBranchRules = function() {
	return this.getActiveRuleSet().branchRules;	
}

/**
 * Get the branch rules for parsing child reference nodes
 */
m3gen.Base.prototype.getReferenceBranchRules = function() {
	return this.getActiveRuleSet().branchRulesRef;
}

// Branch Type Rule

/**
 * Get matching branch type rule for a branch type
 */
m3gen.Base.prototype.getBranchTypeRule = function(branchType) {
	this.getActiveRuleSet().branchTypeRules[branchType];
}

/**
 * Get branch type rule
 * @param {Object} branchType
 */
m3gen.Base.prototype.getBranchTypeRule = function(branchType){
	return this.getActiveBranchTypes()[branchType] ||
	{
		icon: m3gen.constants.branch.defaultFolderIcon,
		state: m3gen.constants.branch.defaultFolderState
	};
}

// Path Method

/**
 * Get the path method to use for finding children
 * Use path method for active ruleSet if exist, otherwise use global config setting, default to 'jpath'
 */
m3gen.Base.prototype.getPathMethod = function() {
	return this.getActiveRuleSet().pathMethod || this.getRuleSetConfiguration().pathMethod ||  'jpath';				
}

// Branch definition

/**
 * Get branch definition from a branch rule
 * @param {Object} branchRule
 */
m3gen.Base.prototype.getBranchDefinition = function(branchRule) {
	return branchRule.branchDef;
};

// Child selectors

/**
 * Get child selectors (list of child selector) from a branch rule
 * @param {Object} branchRule
 */
m3gen.Base.prototype.getChildSelectors = function(branchRule) {
	return branchRule.selectors;
};

// Json reference

/**
 * Try to resolve the entire json model
 */
m3gen.Base.prototype.resolveJsonModel = function() {
	dojox.json.ref.resolveJson(this.getInstanceModel());
};

// Parse Depth

/**
 * maintain count of how deep we have nested
 */
m3gen.Base.prototype.increaseDepth = function(){
	this.depth++;
}

/**
 * maintain count of how deep we have nested
 */
m3gen.Base.prototype.decreaseDepth = function(){
	this.depth--;
}

m3gen.Base.prototype.isValidBranchState = m3gen.util.isValidBranchState;